import "./index.less";
import { Spin } from "ant-design-vue";

export const PageLoading = {
  name: "PageLoading",
  props: {
    tip: {
      type: String,
      default: "",
    },
    size: {
      type: String,
      default: "huge",
    },
    opacity: {
      type: Number,
      default: 1,
    },
  },
  render() {
    const style = {
      textAlign: "center",
      background: `rgba(226,231,239,${this.opacity})`,
      position: "fixed",
      top: 0,
      bottom: 0,
      left: 0,
      right: 0,
      zIndex: 1100,
    };
    const spinStyle = {
      position: "absolute",
      left: "50%",
      top: "40%",
      transform: "translate(-50%, -50%)",
    };
    let clazz = "PageLoading";
    let size = this.size;
    if (this.size === "huge") {
      size = "large";
      clazz += " huge";
    }

    return (
      <div style={style} class={clazz}>
        <Spin size={size} style={spinStyle} tip={this.tip} />
      </div>
    );
  },
};

const loading = {};

loading.newInstance = Vue => {
  let loadingElement = document.querySelector("body>div[type=loading]");
  if (!loadingElement) {
    loadingElement = document.createElement("div");
    loadingElement.setAttribute("type", "loading");
    document.body.appendChild(loadingElement);
  }

  const cdProps = { visible: false, size: "", tip: "", opacity: "" };

  const instance = new Vue({
    data() {
      return {
        ...cdProps,
      };
    },
    render() {
      const { tip, size, opacity } = this;
      const props = {};
      this.tip && (props.tip = tip);
      this.size && (props.size = size);
      this.opacity && (props.opacity = opacity);
      if (this.visible) {
        return <PageLoading {...{ props }} />;
      }
      return null;
    },
  }).$mount(loadingElement);

  function update(config) {
    const { visible, size, tip, opacity } = { ...cdProps, ...config };
    instance.$set(instance, "visible", visible);
    if (tip) {
      instance.$set(instance, "tip", tip);
    }
    if (size) {
      instance.$set(instance, "size", size);
    }
    if (opacity) {
      instance.$set(instance, "opacity", opacity);
    }
  }

  return {
    instance,
    update,
  };
};

const api = {
  show: function(options) {
    this.instance.update({ ...options, visible: true });
  },
  hide: function() {
    this.instance.update({ visible: false });
  },
};

const install = function(Vue) {
  if (Vue.prototype.$loading) {
    return;
  }
  api.instance = loading.newInstance(Vue);
  Vue.prototype.$loading = api;
};

export default install;
